﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using DotNetOpenAuth.OAuth;
using System.Net;

namespace APITwitter.Handlers
{
    public class APIHandler : IHttpHandler
    {
        #region IHttpHandler 成员

        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {

            try
            {
                if (string.IsNullOrEmpty(context.Request.Headers["Authorization"]))
                {
                    context.Response.Clear();
                    context.Response.Write(getResponseFromTwitter(context.Request, string.Empty));
                }
                else
                {
                    string[] authinfo;
                    string username, password;
                    authinfo = Encoding.UTF8.GetString(Convert.FromBase64String(context.Request.Headers["Authorization"].Split(" ".ToCharArray())[1])).Split(":".ToCharArray());
                    username = authinfo[0];
                    password = authinfo[1];
                    string accessToken = getAccessToken(username, password);
                    context.Response.Clear();
                    context.Response.Write(getResponseFromTwitter(context.Request, accessToken));
                }
            }
            catch (Exception ex)
            {
                if (ex is System.IndexOutOfRangeException)
                    sendHttpErrorAndStop(context, 401, new HttpException("Authorization infomation invalid."));
                if (ex is System.Net.WebException)
                    sendHttpErrorAndStop(context, (int)((ex as System.Net.WebException).Response as HttpWebResponse).StatusCode, ex);
                if (ex is HttpException)
                    sendHttpErrorAndStop(context, (ex as HttpException).ErrorCode, ex);
            }
        }

        #endregion

        private string getAccessToken(string username, string password)
        {
            try
            {
                return SQLDBTokenManager.Current.GetAccessTokenByUsernameAndPassword(username, password);
            }
            catch
            {
                throw new HttpException(401, "Invalid username and password");
            }
        }

        private string getResponseFromTwitter(HttpRequest req, string accessToken)
        {
            if (!string.IsNullOrEmpty(accessToken))
                Log.Add(req.Path, accessToken, req.UserHostAddress, req.UserAgent);
            return TwitterConsumer.Current.GetResponseContent(req, accessToken);
        }

        private void sendHttpErrorAndStop(HttpContext context, int code, Exception ex)
        {
            context.Response.Clear();
            context.Response.StatusCode = code;
            context.Response.StatusDescription = ex.Message;
            context.Response.End();
        }

    }
}
